package util;

import org.reflections.Reflections;

import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.util.Set;

/**
 * 反射帮助类
 * 按条件扫描某个包下的类型
 * 使用reflections实现
 *
 * @author wyl
 */
public final class ReflectHelper {


    /**
     * 在指定包下，查找具有指定注解的类型集合
     *
     * @param packageName 包名
     * @param annotation  注解类型
     * @return
     */
    public static Set<Class<?>> findClassByAnnotated(String packageName, Class<? extends Annotation> annotation) {
        Reflections ref = new Reflections(packageName);
        return ref.getTypesAnnotatedWith(annotation);
    }

    /**
     * 在指定包下，查找继承了指定父类型的类型的集合
     *
     * @param packageName 包名
     * @param parentType  父类型
     * @param <T>
     * @return
     */
    public static <T> Set<Class<? extends T>> findClassByParentClass(String packageName, Class<T> parentType) {
        Reflections ref = new Reflections(packageName);
        return ref.getSubTypesOf(parentType);
    }


    /**
     * 获取此类型的父类型的指定索引的泛型参数
     * 若父类型不是泛型则会出错
     * 索引从0开始，超出界限会出错
     *
     * @param type                  指定类型
     * @param genericParameterIndex 泛型参数索引
     * @return
     */
    public static Class<?> getParentClassGenericParameter(Class<?> type, int genericParameterIndex) {
        ParameterizedType t = (ParameterizedType) (type.getGenericSuperclass());
        return (Class<?>) t.getActualTypeArguments()[genericParameterIndex];
    }


}
